
package com.phevos.common.util;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class PollThreadPool
{
    private static List pool = new ArrayList();

    private static final int MAX_THREAD_NUMBER = 50;

    private static Object monitor_pool = new Object();

    private static Logger logger = LoggerFactory.getLogger("PollThreadPool");

    private static final int HOUSE_KEEPER_CYCLE = 5000;// HouseKeeper ÿ5����һ��

    /**
     * ��ȡһ���߳�
     * 
     * @return PollThread �߳�
     */
    public static PollThread getThread()
    {
        PollThread retThread = null;
        synchronized (monitor_pool)
        {
            while (retThread == null)
            {
                int size = pool.size();
                // ��һ��δ�õ��߳�
                for (int i = 0; i < size; i++)
                {
                    PollThread th = (PollThread)pool.get(i);
                    if (!th.used)
                    {
                        retThread = th;
                        break;
                    }
                }
                // δ�ҵ�δ���̣߳��´���һ�����
                if (retThread == null)
                {
                    if (size < MAX_THREAD_NUMBER)
                    {
                        retThread = new PollThread();
                        pool.add(retThread);
                        retThread.start();
                    }
                    else
                    {
                        logger.info("Thread number of pool has reached the max number:"
                                + MAX_THREAD_NUMBER);
                        try
                        {
                            monitor_pool.wait();
                        }
                        catch (InterruptedException ie)
                        {
                            ie.getMessage();
                        }
                    }
                }
            }

            // ������ʹ�ã� ����
            retThread.used = true;
        }
        return retThread;
    }

    /**
     * ���name4�����̳߳��е�һ���߳�
     * 
     * @param name �߳���
     * @return �߳�
     */
    public static PollThread findThread(String name)
    {
        synchronized (monitor_pool)
        {
            int size = pool.size();
            for (int i = 0; i < size; i++)
            {
                PollThread th = (PollThread)pool.get(i);
                if (th.name != null && th.name.equals(name))
                {
                    return th;
                }
            }
        }
        return null;
    }

    /**
     * �ر������߳�
     */
    public static void clear()
    {
        int size = pool.size();
        for (int i = 0; i < size; i++)
        {
            PollThread th = (PollThread)pool.get(i);
            if (th.used)
            {
                th.shutdown();
            }
        }
    }

    /**
     * �ͷ�һ���̣߳����̹߳黹���̳߳���
     * 
     * @param th PollThread
     */
    public static void free(PollThread th)
    {
        synchronized (monitor_pool)
        {
            th.used = false;
            th.name = null;
            monitor_pool.notifyAll();
        }
    }

    /**
     * ����̳߳����̵߳������б?�жϳ�ʱ����Ĵ˴�ִ��
     * <p>
     * Title:
     * </p>
     * <p>
     * Description:
     * </p>
     * <p>
     * Copyright: Copyright (c) 2004
     * </p>
     * <p>
     * Company:
     * </p>
     * 
     * @author wangmh
     * @version 1.0
     */
    private static class HouseKeeper extends Thread
    {
        public void run()
        {
            while (true)
            {
                PollThread[] threads = (PollThread[])pool.toArray(new PollThread[pool.size()]);
                for (int i = 0; i < threads.length; i++)
                {
                    try
                    {
                        PollThread thread = threads[i];
                        if (thread.used)
                        {
                            thread.interruptTimeOutTask();
                        }
                    }
                    catch (Throwable t)
                    {
                        logger.error("House keeper thread ", t);
                    }
                }

                try
                {
                    Thread.sleep(HOUSE_KEEPER_CYCLE);
                }
                catch (InterruptedException ex)
                {
                    ex.getMessage();
                }
            }
        }
    }

    static
    {
        HouseKeeper houseKeeper = new HouseKeeper();
        houseKeeper.start();
    }
}
